package com.api.gbhg.liuwenbo.version3.api;

import com.alibaba.fastjson.JSON;
import com.api.gbhg.liuwenbo.version2.api.BudgetSectionIncomeApi2;
import com.api.gbhg.liuwenbo.version2.api.YearInAndOutBudgetApi;
import com.api.gbhg.liuwenbo.version2.dao.NonCentralTreeDBUtil2;
import com.api.gbhg.liuwenbo.version2.pojo.BudgetSectionIncome2;
import weaver.conn.RecordSet;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;

/**
 * @Description 年度收支预算总表（3.1版本查询所有单位）
 * @Version 3.1
 * @Author lwb
 * @Date 2023.4.12
 */
@Path("v3_1/YearInAndOutBudget")
public class YearInAndOutBudgetApi3_1 {

    private BudgetSectionIncomeApi2 api = new YearInAndOutBudgetApi();

    @POST
    @Path("/getYearInAndOutBudget")
    @Produces(MediaType.APPLICATION_JSON)
    public String getYearInAndOutBudget(Map param){
        Map msgMap = new HashMap<>();
        if (param == null ||!param.containsKey("nf") ||!param.containsKey("jz")){
            msgMap.put("code","500");
            msgMap.put("msg","缺少参数 请检查参数是否完整！");
            msgMap.put("data","");
            return JSON.toJSONString(msgMap);
        }

        Map<String, Object> paramFormat = paramFormat(param);

        List<BudgetSectionIncome2> czbksrData = null;
        List<BudgetSectionIncome2> fczbksrData = null;
        try {
            czbksrData = getCzbksrData(paramFormat);
            fczbksrData = getFczbksrData(paramFormat);

            List<BudgetSectionIncome2> czbksrDataMerge = MergeData(czbksrData);

            Map<String,Object> map = new HashMap<>();
            map.put("中央收入",czbksrDataMerge);
            map.put("非中央收入",structureConversion(fczbksrData,paramFormat.get("nf").toString()));

            msgMap.put("code","200");
            msgMap.put("msg","");
            msgMap.put("data",map);
        }catch (Exception e){
            e.printStackTrace();
            msgMap.put("code","500");
            msgMap.put("msg","程序异常，请联系管理员！"+e.getMessage());
            msgMap.put("data","");
            return JSON.toJSONString(msgMap);
        }
        return JSON.toJSONString(msgMap);
    }

    /**
     * 获取财政拨款收入数据
     * @param param
     * @return
     */
    public List<BudgetSectionIncome2> getCzbksrData(Map<String,Object> param) {

        List<BudgetSectionIncome2> listBean = new ArrayList<>();

        String nf = param.get("nf").toString();
        String dw = param.get("dw").toString();
        String jz = param.get("jz").toString();
        String sql = "select id,gnkmmc,kmdm," + jz + ",yjsr,snjzhpje,yhpje,yqndyjjzje,yjsr,dw from uf_zyczbksr_km where srnf = " + nf;
        if (!dw.equals("") && param.containsKey("dw")) {
            sql += " and dw =" + dw + " ";
        }
        RecordSet rs = new RecordSet();
        System.err.println("获取财政拨款收入数据 " + sql);
        rs.executeQuery(sql);
        while (rs.next()) {
            BudgetSectionIncome2 bean = new BudgetSectionIncome2();
            bean.setDwId(rs.getString("dw"));
            bean.setId(rs.getString("id"));
            bean.setDataid(rs.getString("id"));
            bean.setKmjxj(0);
            bean.setKmmc(rs.getString("kmdm"));
            bean.setSnjz(rs.getString(jz));
            bean.setBnsr(rs.getString("yjsr"));
            bean.setHj(String.valueOf(new BigDecimal(rs.getString(jz)).add(new BigDecimal(rs.getString("yjsr")))));

            //List<BudgetSectionIncome2> xjList = getCzbksrEjData(rs.getString("id"), jz,dw,nf);
            List<BudgetSectionIncome2> xjList = api.getCzbksrEjData(rs.getString("id"), jz, rs.getString("dw"), nf);
            if (xjList.size() > 0) {
                BigDecimal snjzysap = BigDecimal.ZERO;//上年结转预算安排
                BigDecimal bnsrysap = BigDecimal.ZERO;//本年收入预算安排
                BigDecimal snjzwap = BigDecimal.ZERO; //上年结转未安排
                BigDecimal bnsrwap = BigDecimal.ZERO; //本年收入未安排
                BigDecimal snjzyszc = BigDecimal.ZERO; //上年结转预算支出
                BigDecimal bnsryszc = BigDecimal.ZERO; //本年收入预算支出
                BigDecimal snjzyszxl = BigDecimal.ZERO; //上年结转预算执行率
                BigDecimal bnsryszxl = BigDecimal.ZERO; //本年收入预算执行率
                for (BudgetSectionIncome2 beans : xjList) {
                    snjzysap = snjzysap.add(new BigDecimal(beans.getSnjzysap()));
                    bnsrysap = bnsrysap.add(new BigDecimal(beans.getBnsrysap()));

                    snjzwap = snjzwap.add(new BigDecimal(beans.getSnjzwap()));
                    bnsrwap = bnsrwap.add(new BigDecimal(beans.getBnsrwap()));

                    snjzyszc = snjzyszc.add(new BigDecimal(beans.getSnjzyszc()));
                    bnsryszc = bnsryszc.add(new BigDecimal(beans.getBnsryszc()));

                    snjzyszxl = snjzyszxl.add(new BigDecimal(beans.getSnjzyszxl()));
                    bnsryszxl = bnsryszxl.add(new BigDecimal(beans.getBnsryszxl()));
                }
                bean.setSnjzysap(snjzysap.toString());
                bean.setBnsrysap(bnsrysap.toString());
                bean.setHj1(snjzysap.add(bnsrysap).toString());

                bean.setSnjzwap(snjzwap.toString());
                bean.setBnsrwap(bnsrwap.toString());
                bean.setHj2(snjzwap.add(bnsrwap).toString());

                bean.setSnjzyszc(snjzyszc.toString());
                bean.setBnsryszc(bnsryszc.toString());
                bean.setHj3(snjzyszc.add(bnsryszc).toString());

                bean.setSnjzyszxl(snjzyszxl.toString());
                bean.setBnsryszxl(bnsryszxl.toString());
                bean.setHj4(snjzyszxl.add(bnsryszxl).toString());

                bean.setXj(xjList);
            } else {
                //已到最下级  取自身值
                bean.setSnjzysap(rs.getString("snjzhpje"));
                bean.setBnsrysap(rs.getString("yhpje"));
                bean.setHj1(String.valueOf(new BigDecimal(bean.getSnjzysap()).add(new BigDecimal(bean.getBnsrysap()))));

                bean.setSnjzwap(rs.getString("yqndyjjzje"));
                bean.setBnsrwap(rs.getString("yjsr"));
                bean.setHj2(String.valueOf(new BigDecimal(bean.getSnjzwap()).add(new BigDecimal(bean.getBnsrwap()))));

                String snbxje = api.getDfcz_tybxje("0", "1", "0", rs.getString("id"), rs.getString("dw"), nf);
                bean.setSnjzyszc(snbxje);
                String bnbxje = api.getDfcz_tybxje("0", "0", "0", rs.getString("id"), rs.getString("dw"), nf);
                bean.setBnsryszc(bnbxje);
                bean.setHj3(String.valueOf(new BigDecimal(bean.getSnjzyszc()).add(new BigDecimal(bean.getBnsryszc()))));

                BigDecimal snzxl = new BigDecimal("0");
                if (new BigDecimal(bean.getSnjzysap()).compareTo(new BigDecimal("0")) > 0)
                    snzxl = new BigDecimal(bean.getSnjzyszc()).divide(new BigDecimal(bean.getSnjzysap()), 2, BigDecimal.ROUND_HALF_UP);
                bean.setSnjzyszxl(snzxl.toString());

                BigDecimal bnzxl = new BigDecimal("0");
                if (new BigDecimal(bean.getBnsrysap()).compareTo(new BigDecimal("0")) > 0)
                    bnzxl = new BigDecimal(bean.getBnsryszc()).divide(new BigDecimal(bean.getBnsrysap()), 2, BigDecimal.ROUND_HALF_UP);
                bean.setBnsryszxl(bnzxl.toString());
                bean.setHj4(String.valueOf(snzxl.add(bnzxl)));
            }
            bean.setName(rs.getString("gnkmmc"));
            listBean.add(bean);
        }
        return listBean;
    }

    /**
     * 获取非财政拨款收入数据
     * @param param
     * @return
     */
    public List<BudgetSectionIncome2> getFczbksrData(Map<String,Object> param){
        List<BudgetSectionIncome2> listBean = new ArrayList<>();

        Map<String, Object> srysfl = NonCentralTreeDBUtil2.getSrysfl();

        String nf = param.get("nf").toString();
        String dw = param.get("dw").toString();
        String jz = param.get("jz").toString();
        String sql = "select id,szfl,"+jz+",yjsr,snjzhpje,yhpje,yqndyjjzje,yssrfl,sjsr,dw from uf_fzysr where nf = "+nf+" ";
        if(!dw.equals("") && param.containsKey("dw")){
            sql += " and dw ="+dw+" ";
        }
        RecordSet rs = new RecordSet();
        rs.executeQuery(sql);
        while (rs.next()){
            BudgetSectionIncome2 bean = new BudgetSectionIncome2();
            bean.setName(srysfl.get(rs.getString("szfl")).toString());
            bean.setId(rs.getString("szfl"));
            bean.setDwId(rs.getString("dw"));

            List<BudgetSectionIncome2> xjList = api.getFczbksrXm(rs.getString("id"), jz,rs.getString("yssrfl"),rs.getString("dw"),nf);
            if (xjList.size()>0){
//              本级收入
                BudgetSectionIncome2 bj = new BudgetSectionIncome2();
                bj.setKmmc("本级收入");
                bj.setId(rs.getString("szfl"));
                bj.setSnjz(rs.getString(jz));
                bj.setBnsr(rs.getString("yjsr"));
                bj.setHj(String.valueOf(new BigDecimal(rs.getString(jz)).add(new BigDecimal(rs.getString("yjsr")))));
                if (rs.getString("yssrfl").equals("5") || rs.getString("yssrfl").equals("8")) {
                    bj.setSnjzysap(rs.getString("snjzhpje"));
                    bj.setBnsrysap(rs.getString("yhpje"));
                    bj.setHj1(String.valueOf(new BigDecimal(bj.getSnjzysap()).add(new BigDecimal(bj.getBnsrysap()))));
                    bj.setSnjzwap(rs.getString("yqndyjjzje"));
                    bj.setBnsrwap(rs.getString("yjsr"));
                    bj.setHj2(String.valueOf(new BigDecimal(bj.getSnjzwap()).add(new BigDecimal(bj.getBnsrwap()))));

                    String snzc = api.getFzycz_tybxje("1", "1", rs.getString("yssrfl"), rs.getString("id"), rs.getString("dw"), nf, 0);
                    bj.setSnjzyszc(snzc);
                    String bnzc = api.getFzycz_tybxje("1", "0", rs.getString("yssrfl"), rs.getString("id"), rs.getString("dw"), nf, 0);
                    bj.setBnsryszc(bnzc);
                    bj.setHj3(String.valueOf(new BigDecimal(snzc).add(new BigDecimal(bnzc))));

                    BigDecimal snzxl = new BigDecimal("0");
                    if (new BigDecimal(bj.getSnjzysap()).compareTo(new BigDecimal("0"))>0)
                        snzxl = new BigDecimal(bj.getSnjzyszc()).divide(new BigDecimal(bj.getSnjzysap()), 2, BigDecimal.ROUND_HALF_UP);
                    bj.setSnjzyszxl(snzxl.toString());

                    BigDecimal bnzxl = new BigDecimal("0");
                    if (new BigDecimal(bj.getBnsrysap()).compareTo(new BigDecimal("0"))>0)
                        bnzxl = new BigDecimal(bj.getBnsryszc()).divide(new BigDecimal(bj.getBnsrysap()), 2, BigDecimal.ROUND_HALF_UP);
                    bj.setBnsryszxl(bnzxl.toString());
                    bj.setHj4(String.valueOf(snzxl.add(bnzxl)));

                    bj.setBnsjsr(rs.getString("sjsr"));
                }else{
                    bj.setSnjzysap("0");
                    bj.setBnsrysap("0");
                    bj.setHj1("0");
                    bj.setSnjzwap("0");
                    bj.setBnsrwap("0");
                    bj.setHj2("0");

                    bj.setSnjzyszc("0");
                    bj.setBnsryszc("0");
                    bj.setHj3("0");
                    bj.setSnjzyszxl("0");
                    bj.setBnsryszxl("0");
                    bj.setHj4("0");

                    bj.setBnsjsr("0");
                }

                List<BudgetSectionIncome2> bjList = new ArrayList<>();
                bjList.add(bj);

                bjList.addAll(xjList);
                bean.setXj(bjList);
            }

            listBean.add(bean);
        }
        return listBean;
    }
    /**
     * 结构变更
     * @param paramList
     *          数据集合
     * @param nf
     *          年份
     * @return
     */
    public static List<BudgetSectionIncome2> structureConversion(List<BudgetSectionIncome2> paramList, String nf){
        List<BudgetSectionIncome2> list = new LinkedList<>();
        List<BudgetSectionIncome2> resultList = new LinkedList<>();

        for (int i=0;i<paramList.size();i++){
            BudgetSectionIncome2 bean = paramList.get(i);
            bean.setNf(nf);
            List<BudgetSectionIncome2> xjBean = bean.getXj();
            if (xjBean != null && xjBean.size()>0){
                for (int j = 0; j < xjBean.size(); j++) {
                    BudgetSectionIncome2 tempBean = xjBean.get(j);
                    xjChange(tempBean,bean,nf,list);
                }
            }

        }

        for (BudgetSectionIncome2 bean :list) {
            if (resultList.size()==0){
                resultList.add(bean);
            }else{
                int count = 0;
                for (int k=0;k<resultList.size();k++) {
                    BudgetSectionIncome2 v = resultList.get(k);
                    if (v.equals2(bean)){
                        count =1;
                        //需要合并
                        FzysumList(resultList,k,bean);
                    }
                }
                if (count==0)
                    resultList.add(bean);

            }
        }

        return resultList;
    }

    /**
     * 下级结构转换
     * @param xjBean
     *          下级bean
     * @param bean
     *          收入分类bean
     * @param nf
     *          年份
     * @param list
     *          目标集合
     */
    public static void xjChange(BudgetSectionIncome2 xjBean,BudgetSectionIncome2 bean,String nf,List<BudgetSectionIncome2> list) {
        xjBean.setDwId(bean.getDwId());
        xjBean.setNf(nf);

        String dataid = xjBean.getId();
        xjBean.setId(bean.getId());
        xjBean.setName(bean.getName());
        xjBean.setDataid(dataid);

        list.add(xjBean);
    }

    public Map<String,Object> paramFormat(Map<String,Object> param){
        String dw = (!param.containsKey("key") && param.get("dw").equals(""))? "": param.get("dw").toString();
        Integer nf = param.get("nf").equals("")? LocalDate.now().getYear():Integer.parseInt(param.get("nf").toString());
        String jz = param.get("jz").equals("")?"yqndyjjzje":param.get("jz").toString();

        param.put("dw",dw);
        param.put("nf",nf);
        param.put("jz",jz);
        return param;
    }

    //合并数据 同步dataid(下级合并到上级)
    public static List<BudgetSectionIncome2> MergeData(List<BudgetSectionIncome2> listBean){
        List<BudgetSectionIncome2> list = new LinkedList<>();
        for (int i = 0; i < listBean.size(); i++) {

            List<BudgetSectionIncome2> xjList = listBean.get(i).getXj();
            if (xjList !=null && xjList.size()>0){
                for (int j = 0; j < xjList.size(); j++) {
                    sumListDataId(listBean,i,xjList.get(j));
                }
            }

            if (list.size()==0){
                list.add(listBean.get(i));
            }else{
                BudgetSectionIncome2 bean = listBean.get(i);

                int count = 0;
                for (int k=0;k<list.size();k++) {
                    BudgetSectionIncome2 v = list.get(k);
                    if (v.equals2(bean)){
                        count =1;
                        //需要合并
                        sumList(list,k,bean);
                    }
                }
                if (count==0)
                    list.add(bean);

            }

            listBean.get(i).setXj(null);
        }
        return list;
    }

    /**
     * 合并数据 同kmmc+name需要合并
     * @param targetList
     *          目标数据集合
     * @param ix
     *          坐标
     * @param ds
     *          被合并数据
     */
    public static void FzysumList(List<BudgetSectionIncome2> targetList, int ix, BudgetSectionIncome2 ds){
        BudgetSectionIncome2 bean = targetList.get(ix);

        bean.addDataid(ds.getDataid());
        bean.addDwid(ds.getDwId());

        bean.setSnjzysap(new BigDecimal(bean.getSnjzysap()).add(new BigDecimal(ds.getSnjzysap())).toString());
        bean.setBnsrysap(new BigDecimal(bean.getBnsrysap()).add(new BigDecimal(ds.getBnsrysap())).toString());
        bean.setHj1(new BigDecimal(bean.getSnjzysap()).add(new BigDecimal(ds.getBnsrysap())).toString());

        bean.setSnjzwap(new BigDecimal(bean.getSnjzwap()).add(new BigDecimal(ds.getSnjzwap())).toString());
        bean.setBnsrwap(new BigDecimal(bean.getBnsrwap()).add(new BigDecimal(ds.getBnsrwap())).toString());
        bean.setHj2(new BigDecimal(bean.getSnjzwap()).add(new BigDecimal(ds.getBnsrwap())).toString());

        bean.setSnjzyszc(new BigDecimal(bean.getSnjzyszc()).add(new BigDecimal(ds.getSnjzyszc())).toString());
        bean.setBnsryszc(new BigDecimal(bean.getBnsryszc()).add(new BigDecimal(ds.getBnsryszc())).toString());
        bean.setHj3(new BigDecimal(bean.getSnjzyszc()).add(new BigDecimal(ds.getBnsryszc())).toString());

        BigDecimal snzxl = new BigDecimal("0");
        if (new BigDecimal(bean.getSnjzysap()).compareTo(new BigDecimal("0")) > 0)
            snzxl = new BigDecimal(bean.getSnjzyszc()).divide(new BigDecimal(bean.getSnjzysap()), 2, BigDecimal.ROUND_HALF_UP);
        bean.setSnjzyszxl(snzxl.toString());

        BigDecimal bnzxl = new BigDecimal("0");
        if (new BigDecimal(bean.getBnsrysap()).compareTo(new BigDecimal("0")) > 0)
            bnzxl = new BigDecimal(bean.getBnsryszc()).divide(new BigDecimal(bean.getBnsrysap()), 2, BigDecimal.ROUND_HALF_UP);
        bean.setBnsryszxl(bnzxl.toString());
        bean.setHj4(String.valueOf(snzxl.add(bnzxl)));

        //========

        bean.setBnsjsr(new BigDecimal(bean.getBnsjsr()).add(new BigDecimal(ds.getBnsjsr())).toString());
    }

    /**
     * 合并数据 同kmmc+name需要合并
     * @param targetList
     *          目标数据集合
     * @param ix
     *          坐标
     * @param ds
     *          被合并数据
     */
    public static void sumList(List<BudgetSectionIncome2> targetList, int ix, BudgetSectionIncome2 ds){
        BudgetSectionIncome2 bean = targetList.get(ix);

        bean.addDataid(ds.getDataid());
        bean.addDwid(ds.getDwId());
        bean.addId(ds.getId());

        bean.setSnjzysap(new BigDecimal(bean.getSnjzysap()).add(new BigDecimal(ds.getSnjzysap())).toString());
        bean.setBnsrysap(new BigDecimal(bean.getBnsrysap()).add(new BigDecimal(ds.getBnsrysap())).toString());
        bean.setHj1(new BigDecimal(bean.getSnjzysap()).add(new BigDecimal(ds.getBnsrysap())).toString());

        bean.setSnjzwap(new BigDecimal(bean.getSnjzwap()).add(new BigDecimal(ds.getSnjzwap())).toString());
        bean.setBnsrwap(new BigDecimal(bean.getBnsrwap()).add(new BigDecimal(ds.getBnsrwap())).toString());
        bean.setHj2(new BigDecimal(bean.getSnjzwap()).add(new BigDecimal(ds.getBnsrwap())).toString());

        bean.setSnjzyszc(new BigDecimal(bean.getSnjzyszc()).add(new BigDecimal(ds.getSnjzyszc())).toString());
        bean.setBnsryszc(new BigDecimal(bean.getBnsryszc()).add(new BigDecimal(ds.getBnsryszc())).toString());
        bean.setHj3(new BigDecimal(bean.getSnjzyszc()).add(new BigDecimal(ds.getBnsryszc())).toString());

        BigDecimal snzxl = new BigDecimal("0");
        if (new BigDecimal(bean.getSnjzysap()).compareTo(new BigDecimal("0")) > 0)
            snzxl = new BigDecimal(bean.getSnjzyszc()).divide(new BigDecimal(bean.getSnjzysap()), 2, BigDecimal.ROUND_HALF_UP);
        bean.setSnjzyszxl(snzxl.toString());

        BigDecimal bnzxl = new BigDecimal("0");
        if (new BigDecimal(bean.getBnsrysap()).compareTo(new BigDecimal("0")) > 0)
            bnzxl = new BigDecimal(bean.getBnsryszc()).divide(new BigDecimal(bean.getBnsrysap()), 2, BigDecimal.ROUND_HALF_UP);
        bean.setBnsryszxl(bnzxl.toString());
        bean.setHj4(String.valueOf(snzxl.add(bnzxl)));

    }

    public static void sumListDataId(List<BudgetSectionIncome2> targetList, int ix, BudgetSectionIncome2 ds){
        targetList.get(ix).addDataid(ds.getId());

        if (ds.getXj() != null && ds.getXj().size()>0){
            List<BudgetSectionIncome2> xjList = ds.getXj();
            for (int i = 0; i < xjList.size() ; i++) {
                sumListDataId(targetList,ix,xjList.get(i));
            }
        }

    }

}
